home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d2
/
stayres.arc
/
STAYSAVE.340
< prev
next >
Wrap
Text File
|
1988-06-27
|
9KB
|
147 lines
{****************************************************************************}
{ S T A Y S A V E . I N C }
{****************************************************************************}
{This Inline routine will save the regs and Stack for Stay resident programs.
It restores DS and SS from the previously saved integer constants "OurDseg"
and "OurSSeg". This is important since Dos is not re-entrant and any attempt
to use Interrupt I/O services will clobber the very stack on which the
Resident Turbo program just saved its regs. Thus, on the final return, you
and Toto will end up somewhere other than Kansas and without your Ruby Reds.
}
{ author: Copyright (C) Lane Ferris
- The Hunter's Helper -
Distributed to the Public Domain for use without profit.
Original Version 5.15.85
}
{ On entry the Stack will already contain: }
{ 1) Sp for Dos }
{ 2) Bp for Dos }
{ 3) Ip for Dos }
{ 4) Cs for Dos }
{ 5) Flags for Dos }
Inline (
{ The following routine avoids the overhead of saving the DOS stack }
{ when the INT 16 function was not for a character request. This happens }
{ often (every four chars) as DOS checks on ^S/^Q/^C/Keypressed ad.nausea }
$9C/ {PushF Save Flags }
$80/$FC/$00/ {Cmp Ah,00 If Char request, }
$75/$17/ {Jne Skipit Not for us. }
$2E/
$FF/$1E/Dos_Intip/ {Call Far Cs:[Original$16] }
$9C/ {PushF Save Return Flags }
$80/$FC/Our_Char/ {Cmp Ah,Cs:OurChar Our Key? }
$74/$1A/ {Je GotIt enter Staysave code }
{POPF Restore Int 16 flags }
$EB/$01/ {JMP $+3 Skip over IRET }
$CF/ {IRET POP IP/CS/Flags }
$0E/ {PUSH CS Make a return }
$E8/$FB/$FF/ {CALL CS:$-2 Pop the Flags}
$5D/$5D/ {Pop BP/PopBP Restore BP }
$CA/$02/$00/ {RetF 2 Return w/Key discard flags }
{Skipit} {Jmp to Original Dos Intr $16 }
{PopF Restore the Flags }
$EB/$01/ {JMP $+3 Skip over IRET }
$CF/ {IRET POP IP/CS/Flags }
$0E/ {PUSH CS Make a return }
$E8/$FB/$FF/ {CALL CS:$-2 Pop the Flags}
$5D/$5D/ {Pop Bp/Pop Bp else Restore Bp & }
$2E/ { Jump to Original Dos Interrupt }
$FF/$2E/Dos_IntIP/ {Jmp Far Cs:[DOS_IntIp] }
{ Move the current active registers to a safe place}
{GotIt}
{Pop Saved Flags}
$EB/$01/ {JMP $+3 Skip over IRET }
$CF/ {IRET POP IP/CS/Flags }
$0E/ {PUSH CS Make a return }
$E8/$FB/$FF/ {CALL CS:$-2 Pop the Flags}
$FA / {Cli Stop all interrupts }
{ Bp and Sp aready saved at Begin Stmt }
$55/ {Push Bp Save again for Regpak }
$BD/Regs/ {Mov Bp,offset REGS address savearea}
$2E/$89/$46/$00/ {CS:Mov [Bp+0],AX Save Users Registers }
$2E/$89/$5E/$02/ {Cs:Mov [Bp+2],Bx}
$2E/$89/$4E/$04/ {CS:Mov [Bp+4],CX}
$2E/$89/$56/$06/ {CS:Mov [Bp+6],DX}
$2E/$8F/$46/$08/ {Pop Cs:[Bp+8] Fetch Bp from stack }
$2E/$89/$76/$0A/ {CS:Mov [Bp+A],SI}
$2E/$89/$7E/$0C/ {CS:Mov [Bp+C],DI}
$2E/$8C/$5E/$0E/ {CS:Mov [Bp+E],DS}
$2E/$8C/$46/$10/ {CS:Mov [Bp+10],ES}
$9C/ {PUSHF put Flags on stack to retrieve }
$2E/$8F/$46/$12/ {POP Cs:[Bp+12]}
{ If Current SS := [OurSseg] or (Inuse = True), }
{ then dont overlay the previously saved stack. }
{ This program is being recursive. }
$2E/$80/$3E/Inuse/$01/ {Cmp Cs:[Inuse],1 Inuse = True ? }
$74/$62/ {Je ReCurin Yes, -J-U-M-P- }
{ Switch the SS:Sp reg pair over to ES:Si }
{ Put Turbo's Stack pointers into SS:Sp }
$2E/$8C/$16/DosSSeg/ {Mov Cs:DosSSeg,SS Save Dos Stack Segment }
$8C/$D6/ {Mov Si,SS Es gets Dos stack }
$8E/$C6/ {Mov Es,Si }
$2E/$8E/$16/OurSSeg/ {Mov SS,Cs:OurSSeg SS Gets our Stack segment }
$2E/$8E/$1E/OurDseg/ {Mov Ds,Cs:Our_Ds DS Gets our Data Segment }
{ If ES:Si (stack ptr) <> OurSSeg then }
{ Sp := Virgin Turbo Stack pointer. }
{ If Es:Si := OurSSeg, then this is a Read or }
{ Write before Inuse was set True. Dont clobber }
{ the current setting of Turbo stack pointer. }
$2E/$3B/$36/OurSSeg/ {Cmp Si,Cs:OurSSeg If SS := OurSSeg then }
$89/$E6/ {Mov Si,Sp dont clobber saved regs }
$74/$05/ {Je $+5 else get virgin stack ptr }
$3E/$8B/$36/$74/$01/ {Mov Si,Ds:[174] ..(cf. code at B2B 3.0x) }
$87/$F4/ {Xchg Sp,Si Set new Stack Pointer }
{ Stack Dos/User interrupted pgm regs for Exit. }
{ These are the original interrupt process regs }
{ that must be returned on interrupt return }
$2E/$FF/$76/$00/ {Push [Bp+0] Save Ax }
$2E/$FF/$76/$02/ {Push [Bp+2] Save Bx }
$2E/$FF/$76/$04/ {Push [Bp+4] Save Cx }
$2E/$FF/$76/$06/ {Push [Bp+6] Save Dx }
{Push [Bp+8] Save Bp }
$2E/$FF/$76/$0A/ {Push [Bp+A] Save Si }
$2E/$FF/$76/$0C/ {Push [Bp+C] Save Di }
$2E/$FF/$76/$0E/ {Push [Bp+E] Save Ds }
$2E/$FF/$76/$10/ {Push [Bp+10] Save Es }
{ Now stack the lesser of current stack size or }
{ 40 Words to our stack, to be returned on the }
{ interrupted pgms stack on exit. This is done }
{ to allow recursive entry into Dos/or other non }
{ re-entrant pgms. }
$29/$C9/ {Sub Cx,Cx Find minimum of current stack }
$29/$F1/ {Sub Cx,Si size or 40 words to save. }
$D1/$E9/ {Shr Cx,1 Stackbytes/2 for words. }
$83/$F9/$40/ {Cmp Cx,+40 This keeps us from overrunning }
$7E/$03/ {Jle $+3 the Stack Segment when it is less}
$B9/$40/$00/ {Mov Cx,40 than Dos stack size }
$2E/$89/$0E/StackSize/ {Mov Cs:StackSize,Cx Save current stack size }
{Restack:}
$26/$FF/$34/ {Push Es:[Si] Our Stack := Dos Es:Si }
$46/$46/ {Inc Si/Inc Si Get Next Dos Stack Word }
$E2/$F9/ {Loop to Restack }
$56/ {Push Si Save bottom of Dos Stack }
$2E/$8C/$5E/$0E/ {Mov Cs:[Bp+E],Ds Set New Data Segmt in regs}
{Recurin} { Jump here if Recursion }
$FB {Sti Enable Interrupts }
) ;
{...........................................................................}